For our project, we wanted to test different methods and packages to visualize animal movement data. Specifically, we wanted to figure out the best way to create maps and plots to display GPS data.
We wanted to utilize data that was collected and uploaded to Movebank to familiarize ourselves with that platform. We found a unique data set of GPS collared feral cats and European foxes in Australia. These mammals are both invasive to the area. We wanted to communicate their movement patterns and home range sizes in a comparative framework without statistical analyses.
Although we wanted to largely stya away from satistics, some tools are a useful way to visualize differenes in the boundaries of areas being used by individuals. Here, we created minimum convex polygons (MCP) and kernel density estimators (KDE) for three cats and three foxes from August through November in 2017. We wanted to also see if the size of the area the individuals used differed.
# Creating home ranges for cats
# Read in libraries ----
library(dplyr)
## Warning: package 'dplyr' was built under R version 4.1.3
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(lubridate)
##
## Attaching package: 'lubridate'
## The following objects are masked from 'package:base':
##
## date, intersect, setdiff, union
library(amt)
## Warning: package 'amt' was built under R version 4.1.3
##
## Attaching package: 'amt'
## The following object is masked from 'package:stats':
##
## filter
# Read in data ----
# Cat GPS data and reference data
x <- read.csv("Data/Feral cat (Felis catus) - Scotia, NSW-reference-data.csv")
cat <- read.csv("Data/Feral cat (Felis catus) - Scotia, NSW.csv")
# Prepare the data ----
# Filter individuals in 2017 with greater than 600 data pints
cat_choice <- cat %>%
filter(year(timestamp) %in% 2017) %>%
group_by(individual.local.identifier) %>%
summarise(n = length(location.long)) %>%
filter(n >= 600)
# Filter individuals in reference file to see metadata
cat_check <- x %>%
filter(animal.id %in% cat_choice$individual.local.identifier)
# visualize in table the cats per year
table(x$animal.id, x$animal.sex, year(x$deploy.on.date))
## , , = 2016
##
##
## f m
## Arj_MC274 0 0
## Bec_FC232 0 0
## Ben_MC236 0 0
## Col_MC265 0 0
## Con_MC266 0 1
## Fay_FC321 0 0
## Ivy_FC489 0 0
## Jed_MC533 0 1
## Jon_MC566 0 1
## Kay_FC329 0 0
## Ken_MC536 0 1
## Leo_MC536 0 0
## Lyn_FC596 0 0
## Max_MC629 0 0
## Mia_FC642 0 0
## Pam_FC726 0 0
## Ray_MC729 0 0
## Roy_MC769 0 0
## Syd_MC793 0 0
## Ted_MC833 0 0
## Tex_MC839 0 0
## Vic_MC842 0 0
## Wal_MC925 0 0
## Wes_MC937 0 1
## Zac_MC922 0 0
##
## , , = 2017
##
##
## f m
## Arj_MC274 0 0
## Bec_FC232 0 0
## Ben_MC236 0 1
## Col_MC265 0 0
## Con_MC266 0 0
## Fay_FC321 0 0
## Ivy_FC489 1 0
## Jed_MC533 0 0
## Jon_MC566 0 0
## Kay_FC329 1 0
## Ken_MC536 0 1
## Leo_MC536 0 0
## Lyn_FC596 0 0
## Max_MC629 0 1
## Mia_FC642 1 0
## Pam_FC726 0 0
## Ray_MC729 0 1
## Roy_MC769 0 1
## Syd_MC793 0 1
## Ted_MC833 0 0
## Tex_MC839 0 1
## Vic_MC842 0 0
## Wal_MC925 0 0
## Wes_MC937 0 0
## Zac_MC922 0 0
##
## , , = 2018
##
##
## f m
## Arj_MC274 0 1
## Bec_FC232 1 0
## Ben_MC236 0 0
## Col_MC265 0 1
## Con_MC266 0 0
## Fay_FC321 1 0
## Ivy_FC489 1 0
## Jed_MC533 0 0
## Jon_MC566 0 0
## Kay_FC329 0 0
## Ken_MC536 0 1
## Leo_MC536 0 1
## Lyn_FC596 1 0
## Max_MC629 0 0
## Mia_FC642 0 0
## Pam_FC726 1 0
## Ray_MC729 0 0
## Roy_MC769 0 1
## Syd_MC793 0 0
## Ted_MC833 0 1
## Tex_MC839 0 0
## Vic_MC842 0 1
## Wal_MC925 0 1
## Wes_MC937 0 0
## Zac_MC922 0 1
# Grab sex from reference data
sex <- x %>%
select(animal.id,
animal.sex)
# Okay, not lets do some renaming
cat_choice <- cat %>%
filter(year(timestamp) %in% 2017) %>%
# select cols and rename
select(animal.id = individual.local.identifier,
y = location.lat,
x = location.long,
utm.y = utm.easting,
utm.x = utm.northing,
utm.zone,
dt = timestamp) %>%
# join with ref data
left_join(sex, by = "animal.id") %>%
# rename again
rename(sex = animal.sex,
id = animal.id) %>%
# filter time
filter(hour(dt) %in% c(0, 6, 12, 18),
month(dt) %in% 8:11) %>%
# change class of col
mutate(x = as.numeric(x),
y = as.numeric(y),
dt = as.Date(dt)) %>%
# arrange asc date and time
arrange(dt)
# Home range analysis:
# Make track for hr analysis
cat_track <- mk_track(tbl = cat_choice, .x = x, .y = y, .t = dt,
id = id, crs = 23884)
# create hrs per cat
cat <- unique(cat_choice$id)
cat_mcp <- list()
cat_kde <- list()
# loop
for(i in 1:length(cat)){
x <- cat_track %>%
filter(id == cat[i])
cat_mcp[[i]] <- hr_mcp(x = x,
levels = c(0.95, 0.5),
keep.data = TRUE)
# Fit KDE
cat_kde[[i]] <- hr_kde(x = x,
levels = c(0.95, 0.5),
keep.data = TRUE,
h = hr_kde_ref(x), #default
trast = make_trast(x))
}
# name the list elements
names(cat_kde) <- names(cat_mcp) <- cat
# plot: minimum convex Polygon for 3 cats August - November 2017
plot(cat_mcp[[1]], main = "MCP: Ben", col = "coral")
plot(cat_mcp[[2]], main = "MCP: Ivy", col = "lightblue")
plot(cat_mcp[[3]], main = "MCP: Ken", col = "darkolivegreen3")
# plot: Kernel density Estimates for 3 cats August - November 2017
plot(cat_kde[[1]], main = "KDE: Ben", col = "coral")
plot(cat_kde[[2]], main = "KDE: Ivy", col = "lightblue")
plot(cat_kde[[3]], main = "KDE: Ken", col = "darkolivegreen3")
# To extract the areas from all MCPs
mcp_areas <- lapply(cat_mcp, hr_area)
kde_areas <- lapply(cat_kde, hr_area)
c_kde_df <- bind_rows(kde_areas, .id = "id")
c_mcp_df <- bind_rows(mcp_areas, .id = "id")
## tag.id animal.id animal.taxon deploy.on.date
## 1 151-2587 Moe Vulpes vulpes 2015-10-07 20:40:39.000
## 2 150-3603 Jim Vulpes vulpes 2015-10-13 22:00:38.000
## 3 151-2378 Liz Vulpes vulpes 2015-10-19 20:40:38.000
## 4 151-2983 Kim Vulpes vulpes 2015-11-08 20:00:37.000
## 5 150-3987 Mem Vulpes vulpes 2015-11-23 20:40:38.000
## 6 151-2779 Zoe Vulpes vulpes 2015-11-23 22:00:38.000
## 7 151-3384 Ann Vulpes vulpes 2015-11-30 14:00:37.000
## 8 151-3981 Bob Vulpes vulpes 2016-07-31 14:00:36.000
## 9 150-5573 Flo Vulpes vulpes 2016-07-31 14:00:36.000
## 10 150-3987 Reg Vulpes vulpes 2016-07-31 14:00:37.000
## 11 151-2378 Ada Vulpes vulpes 2016-07-31 14:00:37.000
## 12 150-3603 Zoe Vulpes vulpes 2016-07-31 14:00:37.000
## 13 151-1784 Oli Vulpes vulpes 2016-07-31 14:00:37.000
## 14 151-3384 Bea Vulpes vulpes 2016-07-31 14:00:39.000
## 15 151-2779 Cat Vulpes vulpes 2016-07-31 14:01:03.000
## 16 151-3197 Val Vulpes vulpes 2016-08-31 14:00:37.000
## 17 150-3803 Joy Vulpes vulpes 2016-08-31 14:00:38.000
## 18 151-3384 Flo Vulpes vulpes 2017-07-31 14:00:36.000
## 19 150-3603 Don Vulpes vulpes 2017-07-31 14:00:38.000
## 20 151-1784 Ern Vulpes vulpes 2017-07-31 14:00:39.000
## 21 151-2779 Joy Vulpes vulpes 2017-07-31 14:00:39.000
## 22 151-3586 Kev Vulpes vulpes 2017-07-31 14:00:39.000
## 23 151-2378 Ros Vulpes vulpes 2017-07-31 14:00:43.000
## 24 151-2216 Jen Vulpes vulpes 2017-07-31 14:00:44.000
## 25 150-5573 Oli Vulpes vulpes 2017-07-31 14:00:44.000
## 26 151-3197 Lou Vulpes vulpes 2017-07-31 14:01:05.000
## deploy.off.date animal.mass animal.sex attachment.type
## 1 2016-02-02 03:30:44.000 4750 m collar
## 2 2016-01-25 13:40:37.000 4000 m collar
## 3 2016-02-11 12:00:36.000 4000 f collar
## 4 2015-12-04 03:30:48.000 5000 f collar
## 5 2016-01-25 13:40:38.000 3000 f collar
## 6 2016-03-11 12:00:37.000 4000 f collar
## 7 2016-03-11 12:00:36.000 4000 f collar
## 8 2016-09-02 16:01:05.000 4750 m collar
## 9 2016-11-24 12:20:37.000 4550 f collar
## 10 2016-11-25 13:40:37.000 4400 m collar
## 11 2016-11-14 02:12:46.000 3600 f collar
## 12 2016-08-22 11:00:36.000 3650 f collar
## 13 2016-11-24 13:00:38.000 4400 m collar
## 14 2016-11-24 13:00:38.000 3600 f collar
## 15 2016-08-21 18:20:38.000 4650 f collar
## 16 2016-12-23 21:40:37.000 3600 f collar
## 17 2016-12-22 13:20:38.000 3800 f collar
## 18 2017-08-15 07:00:44.000 4400 f collar
## 19 2017-11-21 10:40:36.000 5400 m collar
## 20 2017-10-26 17:40:38.000 4600 m collar
## 21 2017-10-26 18:20:37.000 3600 f collar
## 22 2017-11-20 13:00:38.000 4300 m collar
## 23 2017-10-26 16:00:37.000 4000 f collar
## 24 2017-10-31 12:40:39.000 4100 f collar
## 25 2017-10-31 13:20:38.000 4900 m collar
## 26 2017-11-20 13:00:37.000 3200 m collar
## deploy.off.person deploy.on.person deployment.end.type deployment.id
## 1 Andrew Carter Andrew Carter equipment-failure Moe_151-2587
## 2 Andrew Carter Andrew Carter fall-off Jim_150-3603
## 3 Andrew Carter Andrew Carter fall-off Liz_151-2378
## 4 Andrew Carter Andrew Carter equipment-failure Kim_151-2983
## 5 Andrew Carter Andrew Carter fall-off Mem_150-3987
## 6 Andrew Carter Andrew Carter fall-off Zoe_151-2779
## 7 Andrew Carter Andrew Carter fall-off Ann_151-3384
## 8 Andrew Carter Andrew Carter dead Bob_151-3981
## 9 Andrew Carter Andrew Carter fall-off Flo_150-5573
## 10 Andrew Carter Andrew Carter dead Reg_150-3987
## 11 Andrew Carter Andrew Carter dead Ada_151-2378
## 12 Andrew Carter Andrew Carter dead Zoe_150-3603
## 13 Andrew Carter Andrew Carter fall-off Oli_151-1784
## 14 Andrew Carter Andrew Carter fall-off Bea_151-3384
## 15 Andrew Carter Andrew Carter dead Cat_151-2779
## 16 Andrew Carter Andrew Carter fall-off Val_151-3197
## 17 Andrew Carter Andrew Carter fall-off Joy_150-3803
## 18 Andrew Carter Andrew Carter dead Flo_151-3384
## 19 Andrew Carter Andrew Carter fall-off Don_150-3603
## 20 Andrew Carter Andrew Carter dead Ern_151-1784
## 21 Andrew Carter Andrew Carter dead Joy_151-2779
## 22 Andrew Carter Andrew Carter fall-off Kev_151-3586
## 23 Andrew Carter Andrew Carter dead Ros_151-2378
## 24 Andrew Carter Andrew Carter dead Jen_151-2216
## 25 Andrew Carter Andrew Carter dead Oli_150-5573
## 26 Andrew Carter Andrew Carter fall-off Lou_151-3197
## manipulation.type tag.beacon.frequency tag.comments
## 1 none 151.26 2015 = Moe
## 2 none 150.36 2015 = Jim; 2016 = Zoe; 2017 = Don
## 3 none 151.24 2015 = Liz; 2016 = Ada; 2017 = Ros
## 4 none 151.30 2015 = Kim
## 5 none 150.40 2015 = Mem; 2016 = Reg
## 6 none 151.28 2015 = Zoe; 2016 = Cat; 2017 = Joy
## 7 none 151.34 2015 = Ann; 2016 = Bea; 2017 = Flo
## 8 none 151.40 2016 = Bob; 2017 = Ned
## 9 none 150.56 2016 = Flo; 2017 = Oli
## 10 none 150.40 2015 = Mem; 2016 = Reg
## 11 none 151.24 2015 = Liz; 2016 = Ada; 2017 = Ros
## 12 none 150.36 2015 = Jim; 2016 = Zoe; 2017 = Don
## 13 none 151.18 2016 = Oli; 2017 = Ern
## 14 none 151.34 2015 = Ann; 2016 = Bea; 2017 = Flo
## 15 none 151.28 2015 = Zoe; 2016 = Cat; 2017 = Joy
## 16 none 151.32 2016 = Val; 2017 = Lou
## 17 none 150.38 2016 = Joy; 2017 = Abe
## 18 none 151.34 2015 = Ann; 2016 = Bea; 2017 = Flo
## 19 none 150.36 2015 = Jim; 2016 = Zoe; 2017 = Don
## 20 none 151.18 2016 = Oli; 2017 = Ern
## 21 none 151.28 2015 = Zoe; 2016 = Cat; 2017 = Joy
## 22 none 151.36 2017 = Kev
## 23 none 151.24 2015 = Liz; 2016 = Ada; 2017 = Ros
## 24 none 151.22 2017 = Jen
## 25 none 150.56 2016 = Flo; 2017 = Oli
## 26 none 151.32 2016 = Val; 2017 = Lou
## tag.failure.comments
## 1 Remote drop-off failed. Collar not recovered
## 2
## 3
## 4 Remote drop-off failed. Collar not retreived.
## 5 Last remote download attempt before programmed drop-off date failed.\n\nRemote drop off failed?collar recovered after Reg died.
## 6
## 7 in 2017, collar only collected fixes for ~17 days. Manufacturer suggested flat GPS battery likely cause.
## 8 In 2017, collared collected GPS fixes for 2 days then stopped. Manufacturer suggested GPS battery failure was likely cause.
## 9
## 10 Last remote download attempt before programmed drop-off date failed.\n\nRemote drop off failed?collar recovered after Reg died.
## 11
## 12
## 13
## 14 in 2017, collar only collected fixes for ~17 days. Manufacturer suggested flat GPS battery likely cause.
## 15
## 16
## 17 Faulty VHF signal in 2017. Tag gave mortality signal when the fox was still alive (as confirmed visually by AC)
## 18 in 2017, collar only collected fixes for ~17 days. Manufacturer suggested flat GPS battery likely cause.
## 19
## 20
## 21
## 22
## 23
## 24
## 25
## 26
## tag.manufacturer.name tag.mass tag.model
## 1 Telemetry Solutions 171 Quantum 4000 Enhanced Ext Acc LS26500 SIRFIII
## 2 Telemetry Solutions 175 Quantum 4000 Enhanced Ext Acc LS26500 SIRFIII
## 3 Telemetry Solutions 176 Quantum 4000 Enhanced Ext Acc LS26500 SIRFIII
## 4 Telemetry Solutions 174 Quantum 4000 Enhanced Ext Acc LS26500 SIRFIII
## 5 Telemetry Solutions 175 Quantum 4000 Enhanced Ext Acc LS26500 SIRFIII
## 6 Telemetry Solutions 178 Quantum 4000 Enhanced Ext Acc LS26500 SIRFIII
## 7 Telemetry Solutions 175 Quantum 4000 Enhanced Ext Acc LS26500 SIRFIII
## 8 Telemetry Solutions NA Quantum 4000 Enhanced Ext Acc LS26500 SIRFIII
## 9 Telemetry Solutions NA Quantum 4000 Enhanced Ext Acc LS26500 SIRFIII
## 10 Telemetry Solutions 175 Quantum 4000 Enhanced Ext Acc LS26500 SIRFIII
## 11 Telemetry Solutions 176 Quantum 4000 Enhanced Ext Acc LS26500 SIRFIII
## 12 Telemetry Solutions 175 Quantum 4000 Enhanced Ext Acc LS26500 SIRFIII
## 13 Telemetry Solutions NA Quantum 4000 Enhanced Ext Acc LS26500 SIRFIII
## 14 Telemetry Solutions 175 Quantum 4000 Enhanced Ext Acc LS26500 SIRFIII
## 15 Telemetry Solutions 178 Quantum 4000 Enhanced Ext Acc LS26500 SIRFIII
## 16 Telemetry Solutions 174 Quantum 4000 Enhanced Ext Acc LS26500 SIRFIII
## 17 Telemetry Solutions 178 Quantum 4000 Enhanced Ext Acc LS26500 SIRFIII
## 18 Telemetry Solutions 175 Quantum 4000 Enhanced Ext Acc LS26500 SIRFIII
## 19 Telemetry Solutions 175 Quantum 4000 Enhanced Ext Acc LS26500 SIRFIII
## 20 Telemetry Solutions NA Quantum 4000 Enhanced Ext Acc LS26500 SIRFIII
## 21 Telemetry Solutions 178 Quantum 4000 Enhanced Ext Acc LS26500 SIRFIII
## 22 Telemetry Solutions NA Quantum 4000 Enhanced Ext Acc LS26500 SIRFIII
## 23 Telemetry Solutions 176 Quantum 4000 Enhanced Ext Acc LS26500 SIRFIII
## 24 Telemetry Solutions 177 Quantum 4000 Enhanced Ext Acc LS26500 SIRFIII
## 25 Telemetry Solutions NA Quantum 4000 Enhanced Ext Acc LS26500 SIRFIII
## 26 Telemetry Solutions 174 Quantum 4000 Enhanced Ext Acc LS26500 SIRFIII
## tag.production.date tag.serial.no
## 1 2015 17613615
## 2 2015 17613115
## 3 2015 17613515
## 4 2015 17613815
## 5 2015 17613315
## 6 2015 17613715
## 7 2015 17614015
## 8 2016 37514616
## 9 2016 37519716
## 10 2015 17613315
## 11 2015 17613515
## 12 2015 17613115
## 13 2016 37519816
## 14 2015 17614015
## 15 2015 17613715
## 16 2015 17613915
## 17 2015 17613215
## 18 2015 17614015
## 19 2015 17613115
## 20 2016 37519816
## 21 2015 17613715
## 22 2016 37514416
## 23 2015 17613515
## 24 2015 17613415
## 25 2016 37519716
## 26 2015 17613915
## , , = 2015
##
##
## f m
## Ada 0 0
## Ann 1 0
## Bea 0 0
## Bob 0 0
## Cat 0 0
## Don 0 0
## Ern 0 0
## Flo 0 0
## Jen 0 0
## Jim 0 1
## Joy 0 0
## Kev 0 0
## Kim 1 0
## Liz 1 0
## Lou 0 0
## Mem 1 0
## Moe 0 1
## Oli 0 0
## Reg 0 0
## Ros 0 0
## Val 0 0
## Zoe 1 0
##
## , , = 2016
##
##
## f m
## Ada 1 0
## Ann 0 0
## Bea 1 0
## Bob 0 1
## Cat 1 0
## Don 0 0
## Ern 0 0
## Flo 1 0
## Jen 0 0
## Jim 0 0
## Joy 1 0
## Kev 0 0
## Kim 0 0
## Liz 0 0
## Lou 0 0
## Mem 0 0
## Moe 0 0
## Oli 0 1
## Reg 0 1
## Ros 0 0
## Val 1 0
## Zoe 1 0
##
## , , = 2017
##
##
## f m
## Ada 0 0
## Ann 0 0
## Bea 0 0
## Bob 0 0
## Cat 0 0
## Don 0 1
## Ern 0 1
## Flo 1 0
## Jen 1 0
## Jim 0 0
## Joy 1 0
## Kev 0 1
## Kim 0 0
## Liz 0 0
## Lou 0 1
## Mem 0 0
## Moe 0 0
## Oli 0 1
## Reg 0 0
## Ros 1 0
## Val 0 0
## Zoe 0 0
hist(c_mcp_df$area, main = "MCP: Cat home range area distribution", col = "lightgreen",
xlab = "Area")
hist(c_kde_df$area, main = "KDE: Cat home range area distribution", col = "cyan",
xlab = "Area")
hist(f_mcp_df$area, main = "MCP: Fox home range area distribution", col = "goldenrod",
xlab = "Area")
hist(f_kde_df$area, main = "KDE: Fox home range area distribution", col = "pink",
xlab = "Area")
##Movetrack visualization: cats Now that we can see static home ranges to visualize size and shape variance, we wanted to explore animating the GPS location points to trace the movements of individuals and plot them on a map. The package we used is called moveVis, which requires the data to be formatted as a “movestack” object.
library(tidyverse)
## -- Attaching packages --------------------------------------- tidyverse 1.3.1 --
## v ggplot2 3.3.6 v purrr 0.3.4
## v tibble 3.1.6 v stringr 1.4.1
## v tidyr 1.2.0 v forcats 0.5.2
## v readr 2.1.2
## Warning: package 'ggplot2' was built under R version 4.1.3
## Warning: package 'tibble' was built under R version 4.1.3
## Warning: package 'tidyr' was built under R version 4.1.3
## Warning: package 'readr' was built under R version 4.1.3
## Warning: package 'stringr' was built under R version 4.1.3
## Warning: package 'forcats' was built under R version 4.1.3
## -- Conflicts ------------------------------------------ tidyverse_conflicts() --
## x lubridate::as.difftime() masks base::as.difftime()
## x lubridate::date() masks base::date()
## x amt::filter() masks dplyr::filter(), stats::filter()
## x lubridate::intersect() masks base::intersect()
## x dplyr::lag() masks stats::lag()
## x lubridate::setdiff() masks base::setdiff()
## x lubridate::union() masks base::union()
library(lubridate)
library(move)
## Warning: package 'move' was built under R version 4.1.3
## Loading required package: geosphere
##
## Attaching package: 'geosphere'
## The following object is masked from 'package:amt':
##
## centroid
## Loading required package: sp
##
## Attaching package: 'sp'
## The following object is masked from 'package:amt':
##
## bbox
## Loading required package: raster
##
## Attaching package: 'raster'
## The following object is masked from 'package:amt':
##
## select
## The following object is masked from 'package:dplyr':
##
## select
## Loading required package: rgdal
## Warning: package 'rgdal' was built under R version 4.1.3
## Please note that rgdal will be retired by the end of 2023,
## plan transition to sf/stars/terra functions using GDAL and PROJ
## at your earliest convenience.
##
## rgdal: version: 1.5-32, (SVN revision 1176)
## Geospatial Data Abstraction Library extensions to R successfully loaded
## Loaded GDAL runtime: GDAL 3.4.1, released 2021/12/27
## Path to GDAL shared files: C:/Users/veron/OneDrive - The Pennsylvania State University/Documents/R/win-library/4.1/rgdal/gdal
## GDAL binary built with GEOS: TRUE
## Loaded PROJ runtime: Rel. 7.2.1, January 1st, 2021, [PJ_VERSION: 721]
## Path to PROJ shared files: C:\Program Files\PostgreSQL\13\share\contrib\postgis-3.0\proj
## PROJ CDN enabled: FALSE
## Linking to sp version:1.4-7
## To mute warnings of possible GDAL/OSR exportToProj4() degradation,
## use options("rgdal_show_exportToProj4_warnings"="none") before loading sp or rgdal.
##
## Attaching package: 'move'
## The following object is masked from 'package:amt':
##
## speed
library(moveVis)
## Warning: package 'moveVis' was built under R version 4.1.3
## Find a collection of moveVis animations created by other users on
## Twitter: https://twitter.com/schwalbwillmann
library(RColorBrewer)
## Warning: package 'RColorBrewer' was built under R version 4.1.3
library(leaflet)
## Warning: package 'leaflet' was built under R version 4.1.3
#load cat data from Movebank as Movestack
# create 'login'
loginStored <- movebankLogin(username="mbstum", password="Cq6j9m4KrQRQGJ@")
cats <- getMovebankData("Feral cat (Felis catus) - Scotia, NSW", login = loginStored, includeExtraSensors = TRUE)
# https://cran.r-project.org/web/packages/move/index.html
#subsetting cats dataset as a Movestack object
#visual data exploration to chose cats with the most gps fixes within a similar time period
#subset cats for only Aug - Nov 2017
#list of cats to use
cat_list <- c("Ben_MC236", "Ivy_FC489", "Ken_MC536", "Ray_MC729", "Roy_MC769" )
#subset movestack by cat names
subcats <- cats[[cat_list]]
#subset movestack by year
subcats <- subcats[year(timestamps(subcats))==2017]
#subset movestack by months aug - nov
subcats <- subcats[month(timestamps(subcats))%in% c(8,9,10,11)]
#check timestamps
min(timestamps(subcats))
## [1] "2017-08-01 00:36:43 UTC"
max(timestamps(subcats))
## [1] "2017-11-30 23:00:37 UTC"
# align data to a uniform time scale, resample 4x daily
#reduces frames of movement animation to a resonable time
mC <- align_move(subcats, res = 6, unit = "hours")
## Warning in FUN(X[[i]], ...): CRS object has comment, which is lost in output; in tests, see
## https://cran.r-project.org/web/packages/sp/vignettes/CRS_warnings.html
## Warning in FUN(X[[i]], ...): CRS object has comment, which is lost in output; in tests, see
## https://cran.r-project.org/web/packages/sp/vignettes/CRS_warnings.html
## Warning in FUN(X[[i]], ...): CRS object has comment, which is lost in output; in tests, see
## https://cran.r-project.org/web/packages/sp/vignettes/CRS_warnings.html
## Warning in FUN(X[[i]], ...): CRS object has comment, which is lost in output; in tests, see
## https://cran.r-project.org/web/packages/sp/vignettes/CRS_warnings.html
## Warning in FUN(X[[i]], ...): CRS object has comment, which is lost in output; in tests, see
## https://cran.r-project.org/web/packages/sp/vignettes/CRS_warnings.html
##Interactive location maps Before creating an animation, you can view all the location points for each individual on an interactive map, which allows you to zoom in/out and hover over each point to view information.
#colors for movement tracks
col = brewer.pal(n = 5, name = "Set2")
#create interactive map
view_spatial(mC, path_colours = col, render_as = "leaflet")
##Finally, animate the movement paths into a GIF
# create spatial frames with a basemap
frames <- frames_spatial(mC, path_colours = col,
tail_colour = "white", tail_size = 0.8, #how to include tail
trace_show = TRUE, trace_colour = "darkgray", #how to include path trace
map_service = 'osm', map_type = "terrain",
alpha = 0.5) %>%
add_labels(x = "Longitude", y = "Latitude") %>% # add some customizations, such as axis labels
add_northarrow() %>%
add_scalebar() %>%
add_timestamps(type = "label") %>%
add_progress()
## Checking temporal alignment...
## Processing movement data...
## Approximated animation duration: ˜ 19.36s at 25 fps for 484 frames
## Warning in CPL_crs_from_input(x): GDAL Message 1: +init=epsg:XXXX syntax is
## deprecated. It might return a CRS with a non-EPSG compliant axis order.
## Retrieving and compositing basemap imagery...
## Assigning raster maps to frames...
## Creating frames...
frames[[100]] # preview one of the frames, e.g. the 100th frame
animate_frames(frames, out_file = "catVis.gif", overwrite = TRUE)
## Rendering animation...
## Approximated animation duration: ˜ 19.36s at 25 fps for 484 frames
We also created an interactive map of the fox locations and an animated path of the fox movement during the same time period as the cats.
Notice that with the moveVis package we are able to customize point and line colors, and map imagery.
## # A tibble: 9 x 2
## local_identifier n
## <chr> <int>
## 1 Don 5045
## 2 Ern 3908
## 3 Flo 717
## 4 Jen 3909
## 5 Joy 3150
## 6 Kev 4679
## 7 Lou 5269
## 8 Oli 4215
## 9 Ros 3963
## Warning in FUN(X[[i]], ...): CRS object has comment, which is lost in output; in tests, see
## https://cran.r-project.org/web/packages/sp/vignettes/CRS_warnings.html
## Warning in FUN(X[[i]], ...): CRS object has comment, which is lost in output; in tests, see
## https://cran.r-project.org/web/packages/sp/vignettes/CRS_warnings.html
## Warning in FUN(X[[i]], ...): CRS object has comment, which is lost in output; in tests, see
## https://cran.r-project.org/web/packages/sp/vignettes/CRS_warnings.html
## Warning in FUN(X[[i]], ...): CRS object has comment, which is lost in output; in tests, see
## https://cran.r-project.org/web/packages/sp/vignettes/CRS_warnings.html
## Warning in FUN(X[[i]], ...): CRS object has comment, which is lost in output; in tests, see
## https://cran.r-project.org/web/packages/sp/vignettes/CRS_warnings.html
## Warning in FUN(X[[i]], ...): CRS object has comment, which is lost in output; in tests, see
## https://cran.r-project.org/web/packages/sp/vignettes/CRS_warnings.html
## Warning in FUN(X[[i]], ...): CRS object has comment, which is lost in output; in tests, see
## https://cran.r-project.org/web/packages/sp/vignettes/CRS_warnings.html
## Warning in FUN(X[[i]], ...): CRS object has comment, which is lost in output; in tests, see
## https://cran.r-project.org/web/packages/sp/vignettes/CRS_warnings.html
## Warning in FUN(X[[i]], ...): CRS object has comment, which is lost in output; in tests, see
## https://cran.r-project.org/web/packages/sp/vignettes/CRS_warnings.html
## Checking temporal alignment...
## Processing movement data...
## Approximated animation duration: ˜ 17.96s at 25 fps for 449 frames
## Retrieving and compositing basemap imagery...
## Assigning raster maps to frames...
## Creating frames...
## Rendering animation...
## Approximated animation duration: ˜ 17.96s at 25 fps for 449 frames
## Warning in dir.create(frames_dir, recursive = T): 'C:
## \Users\veron\AppData\Local\Temp\RtmpEBa9Id\moveVis\frames' already exists
The moveVis package works exclusively with objects of class ‘movestack.’ While the package is supposed to allow easy conversion from a data frame to a movestack object, we were not able to successfully make this conversion within moveVis. We resorted to downloading the data directly from Movebank, which requires creating an account and accepting data use terms on the website first. This is not to say converting from a data frame is impossible, but this could make it more difficult for people to use moveVis if they are not housing their GPS data on Movebank.
There are large differences in processing time of the animated map depending on the frequency of location fixes. For example, 2 years of data at 20 minute fixes took several orders of magnitude longer (2 hours) to process than 6 months of data at 6 hour fixes (5 minutes).
Overall, it was quick to get started with the moveVis package, and fairly easy to get a basic map or gif created.
We investigated several other interactive mapping tools.
Leaflet and Mapview are utilized by the moveVis package, so the interactive maps created within moveVis are technically Leaflet maps. However, it is possible to customize interactive maps using Leaflet or Mapview directly. The customization process is very similar to ggplot2, and there are plentiful helpful resources online (https://rstudio.github.io/leaflet/).
Plotly is a commonly used package to upgrade a traditional ggplot to an interactive plot. This can be used for non-spatial data, too!
A package called DynamoVIS (https://dynamovis.geog.ucsb.edu/index) serves a similar purpose as moveVis, but it is not housed on CRAN and it must be downloaded from GitHub. The capabilities appear to be greater than moveVis, but it likely requires more effort from the user.
There were several customizations and visual integrations we hoped to accomplish with moveVis, but were not able to complete. 1. We attempted to set the path (“tail”) colors equal to the animated line, unique to each individual. It seems the package only allows a single parameter value for the tail color, but this is something we could explore further. 2. There is a function in moveVis that allows animated maps to play side-by-side, which would create a useful visualization. There are some underlying steps to align the maps properly, and we simply ran out of time to attempt this mapping feature. 3. Similarly, we wanted to combine the fox and cat movement paths into a single animated map, grouped by species. We encountered difficulties with this goal because the movestack data class can be difficult to manipulate. We have not determined if combining the data sets for a single animated map is impossible in the moveVis package, but we were not able to complete our attempt.